package com.cnjson.sensor.protocolARP.waterQualitySensorProtocol.keepAlive;

import com.cnjson.sensor.db.dao.EquipmeDao;
import com.cnjson.sensor.db.dao.EquipmeStateDao;
import com.cnjson.sensor.db.entity.EquipmentState;
import com.cnjson.sensor.db.utils.IdWorker;
import com.cnjson.sensor.protocolARP.waterQualitySensorProtocol.WaterQualitySensorResolveInterface;
import com.cnjson.sensor.protocolARP.waterQualitySensorProtocol.response.WaterQualitySensorResponse;
import com.cnjson.sensor.util.ByteUtils;
import com.cnjson.sensor.util.DataFormater;
import com.mysql.jdbc.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.nio.channels.SocketChannel;
import java.util.Date;
@Component
public class KeepAlive implements WaterQualitySensorResolveInterface {

    private static final Logger logger = LoggerFactory.getLogger(KeepAlive.class);

    @Autowired
    private EquipmeDao equipmeDao;
    @Autowired
    private EquipmeStateDao equipmeStateDao;
    @Autowired
    private IdWorker idWorker;


    @Override
    public byte[] resolve(String[] data, SocketChannel client) {


        logger.info(Thread.currentThread().getId() +"心跳中");
        byte[] response = null;
        // 心跳类型 1：链路心跳，2：状态心跳
        /*
         * response = new byte[subLeng + 4];
         * System.arraycopy(dataLen.array(), 0, response, 0, 4);
         * System.arraycopy(data.array(), 0, response, 4,
         * subLeng); response[2] = (byte) 0xAF; response[6] =
         * 0x00; byte[] crcTemp = new byte[subLeng - 3];
         * System.arraycopy(response, 3, crcTemp, 0,
         * response.length - 7); byte[] nR =
         * CRC16.getCrcBytes(crcTemp); System.arraycopy(nR, 0,
         * response, response.length - 4, 2);
         */
        try {


            int type = Integer.parseInt(data[11]);
            byte[] content = null;// 应答内容，不同类型不同内容


            //4位地址
            String device=data[7]+data[8]+data[9]+data[10];
            byte[] deviceBytes= ByteUtils.hexStringToBytes(device);

            // 链路心跳
            if (type == 1) {
                content = new byte[]{0x01, 0x00};
            } else if (type == 2) {
                content = new byte[4];
                content[0] = 0x02;
                content[1] = 0x00;
                content[2] = 0x00;
                content[3] = 0x00;
            } else {
                content = new byte[23];
                content[0] = 0x02;
                content[1] = 0x00;

                content[2] = 0x00;// 如果要同步时间，必须修改1，同时把正确时间下发。
                content[3] = 0x00;

               StringBuilder sb=new StringBuilder(19);
                //14 ->  32
               for(int i=0;i<19;i++)
                   sb.append(data[14]);
                byte[] bytes=ByteUtils.hexStringToBytes(sb.toString());

                System.arraycopy(bytes, 0, content, 4, 19);


            }

            response = WaterQualitySensorResponse.buildResponsePackage((byte) 0x43, deviceBytes, content);

            // update col_equipment_state
            // 判断记录是否存在用于insert/update

            updateEquipmentStateByHeart(data, client);

            logger.info("----------0x43 接收设备心跳并返回:" + DataFormater.bytesToHexString(response) + "----");
        } catch (Exception e) {
            logger.error("----------0x43异常：-----------" + e);
        }
        return response;
    }



    /**
     * 根据心跳更新设备状态
     *
     * @param data
     */
    private void updateEquipmentStateByHeart(String[] data, SocketChannel client) throws IOException {

        // 2位设备地址段
        String address = data[7]+data[8];
        String id = equipmeStateDao.findIdByEquipmentId(address);//根据equipment_id获取当前设备状态记录（ift_equipment_status）的id


        String heartbean = data[11];
        String linkType = data[13];

        //这里的时间如果错了的话，从13开始，那么其他的位数应该都错了要退一位
        String date1=data[14]+data[15]+data[16]+data[17]+data[18]+data[19];
        byte[] dateBytes= ByteUtils.hexStringToBytes(date1);
        Date sDate = DataFormater.bytesToDate(dateBytes);

        String reportCycle = data[20]+data[21]+data[22]+data[23];
        String acquisionCycle = data[24]+data[25]+data[26]+data[27];
        String storageCycle = data[28]+data[29]+data[30]+data[31];
        String signal =data[32];
        int storedData = Integer.parseInt( data[33]+data[34]+data[35]+data[36]);
        int unreportedData = Integer.parseInt( data[37]+data[38]+data[39]+data[40]);
        String ee =  data[41]+data[42]+data[43]+data[44];
        Float equipmentEnergy = Float.intBitsToFloat(Integer.parseInt(ee, 16));


        logger.info("心跳收到的数据"+
                "heart "+heartbean+"link"+linkType+"time"+sDate
                +"reportCycle"+reportCycle+"acquisionCycle"+acquisionCycle+
                "storageCycle"+storageCycle+"signal"+signal+"storedData"+storedData
                +"unreportedData"+unreportedData+"equipmentEnergy"+equipmentEnergy);
        
        
        // EquipmentStateService service = new EquipmentStateService();
        String equipmentId = equipmeDao.findIdByNumber(address);
        if (StringUtils.isNullOrEmpty(equipmentId)) {
            logger.warn("---------0x43 设备未配置-------------");
            return;
        }



        Date date = new Date();
        String remote = client.getRemoteAddress().toString();
        if (!StringUtils.isNullOrEmpty(id)) {
            // update
            EquipmentState e = new EquipmentState(id);
            e.setRunningState("1");
            e.setCurTime(date);
            e.setCommunicationTime(sDate);
            e.setSignalIntensity(signal);
            e.setHeartbeatType(heartbean);
            e.setLinkType(linkType);
            e.setReportingCycle(reportCycle);
            e.setAcquisionCycle(acquisionCycle);
            e.setStorageCycle(storageCycle);
            e.setStoredData(storedData);
            e.setUnreportedData(unreportedData);
            e.setEquipmentEnergy(equipmentEnergy);
            e.setUpdateBy("");
            e.setUpdateDate(date);
            e.setDelFlag("0");
            e.setRemoteAddress(remote);
            equipmeStateDao.save(e);
        } else {
            // insert
            EquipmentState e = new EquipmentState();
            e.setId(idWorker.nextId()+"");
            e.setEquipmentId(address);
            e.setRunningState("1");
            e.setCurTime(date);
            e.setCommunicationTime(sDate);
            e.setSignalIntensity(signal);
            e.setHeartbeatType(heartbean);
            e.setLinkType(linkType);
            e.setReportingCycle(reportCycle);
            e.setAcquisionCycle(acquisionCycle);
            e.setStorageCycle(storageCycle);
            e.setStoredData(storedData);
            e.setUnreportedData(unreportedData);
            e.setEquipmentEnergy(equipmentEnergy);
            e.setCreateBy("");
            e.setCreateDate(date);
            e.setUpdateDate(date);
            e.setDelFlag("0");
            e.setRemoteAddress(remote);
            equipmeStateDao.save(e);
        }
    }

}
